#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "uthash.h" // 哈希表

#include "utils.h"

/**
 * gcc directIO.c -D_GNU_SOURCE && ./a.out ../blkparse/14.blkparse data meta
*/

#define BLKSZ 4096
#define FPSZ 256
#define MD5_STEP 256 // 哈希读取步长
#define MD5_READ_SZ FPSZ // 每次传过去的大小, 设置成FPSZ防止哈希碰撞
#define BOFFSET_BITS 8
#define BINDEX(x) (x >> BOFFSET_BITS)
#define BOFFSET(x) (x & ((1 << BOFFSET_BITS) - 1))
#define GEN_ENTRYID(bindex, boffset) ((bindex << BOFFSET_BITS) | boffset)
#define SMALL_FPSZ 20 // 暂时不会用xxhash, entry中的FPSZ先直接用这个代替

#define calcHash(output, input) calcHashSimple(output, input, FPSZ)

typedef uint32_t bn_t;
struct LBN2PBN {
	bn_t lbn; // key
	bn_t entryid; // value
    UT_hash_handle hh;
};

struct fp2PBN {
	char fp[FPSZ]; // key
	bn_t entryid; // value
    UT_hash_handle hh;
};

/*声明哈希为NULL指针*/
struct LBN2PBN *l2p_ht = NULL;
struct fp2PBN *f2p_ht = NULL;

struct metadata_entry {
    char fp[SMALL_FPSZ];
    bn_t pbn;
    char ref;
};

#define ENTRY_PER_BLK_DEF (BLKSZ\
        -sizeof(bn_t)-sizeof(uint32_t))\
        / sizeof(struct metadata_entry)
// #define ENTRY_PER_BLK_DEF 1

const uint32_t ENTRY_PER_BLK = ENTRY_PER_BLK_DEF;

struct metadata_blk {
    bn_t blockid;
    uint32_t valid_num;
    struct metadata_entry entries[ENTRY_PER_BLK_DEF];
}__attribute__((aligned(BLKSZ)));

// 统计变量
int dupcnt = 0, editcnt = 0;

#ifndef FSYNCSTEP
#define FSYNCSTEP 5
#endif
